<?php

namespace app\modules\backend\controllers;

use app\models\tableModel\NewsModel;
use app\models\tableModel\UserModel;
use app\service\CacheService;
use app\service\tool\ConvertService;
use app\service\tool\GenerateService;
use app\service\tool\UtilsService;
use yii\console\Exception as consoleException;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

/**
 * 统计数据
 */
class StatisticsController extends BaseController
{

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs'  => [ // 请求方式
                'class'   => VerbFilter::className(),
                'actions' => [
                    ### 页面

                    ### 接口
                    'setting'     => ['GET'],
                    'simple-user' => ['GET'],
                    'simple-news' => ['GET'],
                    'sum-news' => ['GET']
                ],
            ]
        ];
    }

    /**
     * 获取设置
     * @param bool $returnJson 返回数据格式是否[json]
     * @return int[]|\yii\console\Response|\yii\web\Response
     */
    public function actionSetting($returnJson = true)
    {

        // 类型 - 一般为首页[index]、表单[form]
        $type = $this->get('type');
        $data = [
            'maxInterval' => 15, // 时间查询自定义时间，最大间隔，比如4-20~4-21中间最大间隔天数
            'duration'    => 1200,  // 缓存过期时间
        ];
        return $returnJson ? $this->jsonSuccess('成功', $data) : $data;
    }

    /**
     * 简报统计[前台用户]数据
     * @return mixed
     */
    public function actionSimpleUser()
    {

        // 时间类型
        $timeType = $this->get('time_type', 'day');

        ### 缓存配置
        $cache = CacheService::loadModel([
            'cacheType' => CacheService::getTypeMemcache(),// 缓存类型
            'cacheKey'  => CacheService::getCacheKey('stats_simple_user') // 键
        ]);
        // 缓存有数据直接返回
        $cacheData = $cache->get();
        if (!empty($cacheData['data'][$timeType])) {
            return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
        }

        ### 查询的时间
        // 设置
        $setting = $this->actionSetting(false);
        if ($timeType != 'custom') {
            // 不是自定义时间，走某些特定时间 - 获取特定时间范围时间戳
            $timeList = GenerateService::getTimeList($timeType);
        } else {
            // 自定义时间，格式化初始、结束时间为时间戳
            $timeRange = $this->get('time_range');
            $timeList  = GenerateService::getTimeListForRange(
                'day', $timeRange[0], $timeRange[1], $setting['maxInterval']
            );
        }

        ### 执行查询 && 塑造数据
        $data = [];
        foreach ($timeList as $k => $v) {

            $data[] = [
                'text' => $v['text'],
                'data' => UserModel::loadModel()->loadWhere([
                    'AND',
                    ['between', 'add_time', $v['start_time'], $v['end_time']]
                ])->getPaginate(1, 1, 'id')->getTotal()
            ];
        }

        ### 上个数据查询
        $lastSum = 0;
        if ($timeType != 'custom') {

            $startTime = empty($timeList[0]['start_time']) ? 0 : $timeList[0]['start_time'];
            // 时间区间
            $timeList = GenerateService::getTimeRange(
                'day', $startTime - 1
            );

            $lastSum = UserModel::loadModel()->loadWhere([
                'AND',
                ['between', 'add_time', $timeList['start_time'], $timeList['end_time']]
            ])->getPaginate(1, 1, 'id')->getTotal();
        }


        ### 写入缓存
        // 开始塑造缓存数据
        $times = time();
        // 根据事件类型存储
        $cacheData['data'][$timeType] = [
            'list'            => $data,
            'sum'             => array_sum(array_column($data, 'data')),
            'last_sum'        => $lastSum,
            'cache_time'      => $times,
            'cache_time_text' => date('Y-m-d H:i:s', $times)
        ];
        // 返回结果
        if (!$cache->set(false, $cacheData, $setting['duration'])) {
            return $this->jsonFail('数据加载失败', 400, [
                'error_hint' => '缓存失败'
            ]);
        }

        return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
    }

    /**
     * 简报统计[文章]数据
     * @return mixed
     */
    public function actionSimpleNews()
    {

        // 时间类型
        $timeType = $this->get('time_type', 'day');

        ### 缓存配置
        $cache = CacheService::loadModel([
            'cacheType' => CacheService::getTypeMemcache(),// 缓存类型
            'cacheKey'  => CacheService::getCacheKey('stats_simple_news') // 键
        ]);
        // 缓存有数据直接返回
        $cacheData = $cache->get();
        if (!empty($cacheData['data'][$timeType])) {
            return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
        }

        ### 查询的时间
        // 设置
        $setting = $this->actionSetting(false);
        if ($timeType != 'custom') {
            // 不是自定义时间，走某些特定时间 - 获取特定时间范围时间戳
            $timeList = GenerateService::getTimeList($timeType);
        } else {
            // 自定义时间，格式化初始、结束时间为时间戳
            $timeRange = $this->get('time_range');
            $timeList  = GenerateService::getTimeListForRange(
                'day', $timeRange[0], $timeRange[1], $setting['maxInterval']
            );
        }

        ### 执行查询 && 塑造数据
        $data = [];
        foreach ($timeList as $k => $v) {

            $data[] = [
                'text' => $v['text'],
                'data' => NewsModel::loadModel()->loadWhere([
                    'AND',
                    ['between', 'add_time', $v['start_time'], $v['end_time']]
                ])->getPaginate(1, 1, 'id')->getTotal()
            ];
        }

        ### 上个数据查询
        $lastSum = 0;
        if ($timeType != 'custom') {

            $startTime = empty($timeList[0]['start_time']) ? 0 : $timeList[0]['start_time'];
            // 时间区间
            $timeList = GenerateService::getTimeRange(
                'day', $startTime - 1
            );

            $lastSum = NewsModel::loadModel()->loadWhere([
                'AND',
                ['between', 'add_time', $timeList['start_time'], $timeList['end_time']]
            ])->getPaginate(1, 1, 'id')->getTotal();
        }


        ### 写入缓存
        // 开始塑造缓存数据
        $times = time();
        // 根据事件类型存储
        $cacheData['data'][$timeType] = [
            'list'            => $data,
            'sum'             => array_sum(array_column($data, 'data')),
            'last_sum'        => $lastSum,
            'cache_time'      => $times,
            'cache_time_text' => date('Y-m-d H:i:s', $times)
        ];
        // 返回结果
        if (!$cache->set(false, $cacheData, $setting['duration'])) {
            return $this->jsonFail('数据加载失败', 400, [
                'error_hint' => '缓存失败'
            ]);
        }

        return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
    }

    /**
     * 汇总统计[文章]数据
     * @return mixed
     */
    public function actionSumNews()
    {

        // 时间类型
        $timeType = $this->get('time_type', 'day');

        ### 缓存配置
        $cache = CacheService::loadModel([
            'cacheType' => CacheService::getTypeMemcache(),// 缓存类型
            'cacheKey'  => CacheService::getCacheKey('stats_sum_news') // 键
        ]);
        // 缓存有数据直接返回
        $cacheData = $cache->get();
        if (!empty($cacheData['data'][$timeType])) {
             return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
        }

        ### 查询的时间
        // 设置
        $setting = $this->actionSetting(false);
        if ($timeType != 'custom') {
            // 不是自定义时间，走某些特定时间 - 获取特定时间范围时间戳
            $timeList = GenerateService::getTimeList($timeType);
        } else {
            // 自定义时间，格式化初始、结束时间为时间戳
            $timeRange = $this->get('time_range');
            $timeList  = GenerateService::getTimeListForRange(
                'day', $timeRange[0], $timeRange[1], $setting['maxInterval']
            );
        }

        ### 执行查询 && 塑造数据
        $data = [];
        $statusList = NewsModel::getStatusList();
        foreach ($timeList as $k => $v) {

            foreach ($statusList as $sk => $sv) {
                $data[$sv['value']] = [
                    'text' => $sv['text'],
                    'value' => $sv['value'],
                    'data' => NewsModel::loadModel()->loadWhere([
                        'AND',
                        ['=', 'status', $sv['value']],
                        ['between', 'update_time', $v['start_time'], $v['end_time']]
                    ])->getPaginate(1, 1, 'id')->getTotal() +
                    empty($data[$sv['value']]['data']) ? 0 : $data[$sv['value']]['data']
                ];
            }
        }
        $data = array_values($data);

        ### 写入缓存
        // 开始塑造缓存数据
        $times = time();
        // 根据事件类型存储
        $cacheData['data'][$timeType] = [
            'list'            => $data,
            'cache_time'      => $times,
            'cache_time_text' => date('Y-m-d H:i:s', $times)
        ];
        // 返回结果
        if (!$cache->set(false, $cacheData, $setting['duration'])) {
            return $this->jsonFail('数据加载失败', 400, [
                'error_hint' => '缓存失败'
            ]);
        }

        return $this->jsonSuccess('成功', $cacheData['data'][$timeType]);
    }
}
